/**
 * @description: 角色标签 元素
 * @fileName: index
 * @author: 17076
 * @date: 2025/4/17-下午1:41
 * @version: V1.0.0
 **/
import { DomEditor, SlateTransforms } from '@wangeditor/editor'
import { h } from 'snabbdom'
import Vue from 'vue'
import RoleTag from './RoleTag.vue'

const elMap = new WeakMap()

export default {
  editorPlugin: function(editor) { // JS 语法
    const { isInline, isVoid } = editor
    const newEditor = editor
    newEditor.isInline = elem => {
      const type = DomEditor.getNodeType(elem)
      if (type === 'roleTag') return true // 针对 type: attachment ，设置为 inline
      return isInline(elem)
    }
    newEditor.isVoid = elem => {
      const type = DomEditor.getNodeType(elem)
      if (type === 'roleTag') return true // 针对 type: attachment ，设置为 void
      return isVoid(elem)
    }
    return newEditor // 返回 newEditor ，重要！！！
  }, // 插件
  renderElems: [{
    type: 'roleTag', // 新元素 type ，重要！！！
    renderElem: function(elem, children, editor) {
      const isDisabled = editor.isDisabled()
      const selected = DomEditor.isNodeSelected(editor, elem)
      const { vueValue } = elem
      // 附件元素 vNode
      const node = h(
        // HTML tag
        'span',
        // HTML 属性、样式、事件
        {
          props: {
            contentEditable: false
          }, // HTML 属性，驼峰式写法
          style: {
            display: 'inline-block',
            padding: '3px',
            marginLeft: '3px',
            marginRight: '3px',
            cursor: 'pointer',
            border:
              selected && !isDisabled
                ? '1px solid #12DBFF' // wangEditor 提供了 css var https://www.wangeditor.com/v5/theme.html
                : '1px solid transparent',
            borderRadius: '4px'
          }, // style ，驼峰式写法
          dataset: {
            vueValue
          },
          hook: {
            insert(vNode) {
              const el = vNode.elm
              const instance = new Vue({
                ...RoleTag,
                propsData: {
                  disabled: editor.isDisabled(),
                  defaultValue: el.dataset.vueValue,
                  updateValue: value => {
                    // 更新slate node的值，为了删除撤回是，节点是删除时的数据，而不是初始数据
                    // const { elem } = elMap.get(vnode.elm)
                    const location = DomEditor.findPath(editor, elem)
                    SlateTransforms.setNodes(editor, {
                      vueValue: value
                    }, {
                      at: location
                    })
                  }
                }
              }).$mount()
              el.innerHTML = ''
              el.appendChild(instance.$el)
              elMap.set(vNode.elm, instance)
            },
            destroy(vNode) {
              const instance = elMap.get(vNode.elm)
              if (instance) {
                instance.$destroy()
              }
              elMap.delete(vNode.elm)
            }
          }
        }
      )
      return node
    }
  }],
  elemsToHtml: [{
    type: 'roleTag', // 新元素的 type ，重要！！！
    elemToHtml: function(elem) {
      const vueValue = elem.vueValue
      // 生成 HTML 代码
      return `<span data-w-e-type="roleTag" data-vue-value="${vueValue}">${vueValue}</span>`
    }
  }], // elemToHtml
  parseElemsHtml: [{
    selector: `span[data-w-e-type="roleTag"]`, // CSS 选择器，匹配特定的 HTML 标签
    parseElemHtml: function(domElem) {
      const vueValue = domElem.getAttribute('data-vue-value') || ''
      return {
        type: 'roleTag',
        vueValue,
        children: [{ text: '' }] // void node 必须有 children ，其中有一个空字符串，重要！！！
      }
    }
  }] // parseElemHtml
}

